Type TCar 
	Field mesh 
    Field name$	
	Field speed#
	
	
	Field is_Player 
	
	Field wayp.TWayPoint 
	Field count_waypoint 
	
	
	Field nb_loop
	Field MaX_loop	
	Field Race_pos_factor 
	Field Race_pos
	
	
	; Field Use to store current item selected
	; item bomb
	Field bExploded
	Field WaitExplodeTime.Timer
	Field OldX#,OldY#,OldZ#
	
	; item speed
	Field bSpeed
	Field WaitSpeedTime.Timer
	Field oldspeed#
	
	; item missil
	Field bMissil
	Field MissilLaunchTime.Timer
	Field MissilMesh
	Field MissilTarget.TCar
	
	
	; Create a LOS instance 
	Field Los.TLOS
	
	Field body ; body handle for physics engine
	
End Type 



Function TCar_CreateVoiture.TCar(p_bIsHuman=False)   
	Local l_c.TCar=New TCar 
	
	l_c\mesh	=	CopyEntity    (g_App\MDL) 
    
	l_c\speed# = 10.0
	l_c\oldspeed# = 10.0
	
    l_c\is_Player = p_bIsHuman
    
    
	l_c\count_waypoint = TWayPoint_Count()
    l_c\wayp = Null
    
    l_c\wayp = TWayPoint_Get(1)
    
    l_c\nb_loop = 0
    l_c\MaX_loop = p_Max_loop_to_do
    uCelShading( l_c\mesh,0,0,0,0.1)
    
    
    l_c\bExploded=False
    l_c\WaitExplodeTime=Null
	
    l_c\bSpeed=False
    l_c\WaitSpeedTime=Null
    l_c\oldspeed=l_c\speed
	
    l_c\MissilLaunchTime = Null
    l_c\MissilMesh = 0
    
    l_c\Los = TLOS            ( 7, 60 ) 
    
    l_c\body = BodyCreateHull(l_c\mesh,1)
	
    phBodySetMass( l_c\body, 600 )
    
    Return l_c 
End Function 


Function TCar_SetName( p_c.TCar, p_sName$)
	p_c\name = Upper( p_sName$ )
End Function

Function TCar_SetSpeed.TCar( p_sName$, p_speed#=10.0 )  
	
	Local l_c.TCar = TCar_GetByName( Upper(p_sName$) )
    l_c\speed = p_speed#
End Function 

Function TCar_SetColor.TCar( p_sName$, p_R, p_G, p_B )
	Local l_c.TCar = TCar_GetByName( Upper(p_sName$) )
	EntityColor l_c\mesh,p_R, p_G, p_B
End Function 


Function TCar_SetMeshByBody( c.TCar )
	phSetMeshByBody( c\mesh, c\body )
End Function 


Function TCar_SetBodyByMesh( c.TCar )
	phSetBodyByMesh( c\body, c\mesh )
End Function  

Function TCar_GetByName.TCar( p_name$ )
	Local c.TCar = Null 
	For c.TCar=Each TCar
		If Upper(c\name) = Upper(p_name)
			Return c
			Exit 
		End If
	Next 
	Return Null 
End Function 


Function TCar_Update_Camera()
	If KeyHit(15) ; 15 = TAB SPACE
		g_App\UserCamMode = g_App\UserCamMode + 1
		If g_App\UserCamMode > 4 Then g_App\UserCamMode = 0
 	EndIf 
	
	; 5 cam mode 
	If g_App\UserCamMode > 0
		uCamera3rdPers( g_App\Cam1, g_App\Player\mesh,5*g_App\UserCamMode,-8*g_App\UserCamMode,0.1 ) 
	ElseIf g_App\UserCamMode = 0
		PositionEntity g_App\Cam1, EntityX( g_App\Player\mesh ), EntityY( g_App\Player\mesh )+40, EntityZ( g_App\Player\mesh ) 
		PointEntity g_App\Cam1, g_App\Player\mesh
	EndIf 
End Function 

Function TCar_Update_Item(c.TCar)
	If c\bExploded = True 
		If TimeOut(c\WaitExplodeTime)
			c\bExploded = False
			phBodySetVel(c\body, 0, 0, 0)
			phBodySetPos(c\body, c\OldX, c\OldY+7, c\OldZ)
			PositionEntity c\mesh, c\OldX, c\OldY+7, c\OldZ
			ShowEntity c\mesh
		Else
				;wait
		EndIf 
		Return False 
	EndIf 	
	
	If c\bMissil = True And KeyDown(29)  
		c\bMissil = False
		
		m = CopyEntity(g_App\TEMPLATE_MISSIL) 
		PositionEntity m, EntityX( c\mesh ), EntityY( c\mesh ), EntityZ( c\mesh )
		
		c\MissilMesh = m
		c\MissilLaunchTime = SetTimer( Rand(3000) )
		c\MissilTarget = TCar_GetNearest( c )
		PointEntity c\MissilMesh,c\MissilTarget\mesh 
	EndIf 	
	
	If TimeOut( c\MissilLaunchTime ) = False And c\MissilMesh <> 0
		uSmoothPoint( c\MissilMesh, c\MissilTarget\mesh, 1 )
		MoveEntity c\MissilMesh, 0,0,1
		
		Local other.TCar
		For other.TCar = Each TCar
			If other\name <> c\name And c\MissilMesh > 0
				If EntityDistance( other\mesh, c\MissilMesh ) < 1 Then
					TExplosion_Create( c\MissilMesh,1 )
					TExplosion_Create( other\mesh,1 )
					other\bExploded=True
					other\WaitExplodeTime=SetTimer(2000)
					FreeEntity(c\MissilMesh)
					c\MissilMesh=0
					c\MissilTarget=Null
				EndIf 
			EndIf 
		Next 
	ElseIf TimeOut( c\MissilLaunchTime )  
		FreeEntity c\MissilMesh
		c\MissilLaunchTime = Null
		c\MissilMesh = 0
		c\MissilTarget = Null
		c\bMissil = False 
	EndIf
	
	Return True 
End Function 

Function TCar_UserControl(c.TCar)
	TCar_Update_Camera()
	
	
	
	Local l_bisGoBack=False
	; user can move the car only when car touch the floor.
	If EntityY(c\mesh) > 0 Then Return 
	
	
	
	If KeyDown(200) ; UP
		TFormVector 0,0,c\speed,c\mesh,0
		phBodySetVel( c\body, TFormedX() , TFormedY(), TFormedZ() );<NWT>
	EndIf 		
	
	If KeyDown(208) ; Down
		l_bisGoBack=True 
		TFormVector 0,0,-(c\speed)*.5,c\mesh,0
		phBodySetVel( c\body, TFormedX() , TFormedY(), TFormedZ() ) ;<NWT>
	EndIf 
	
	If KeyDown(203) ;Right
		If l_bisGoBack = False 
			phBodySetRot( c\body, phBodyGetPitch(c\body), phBodyGetYaw(c\body)+2.0, phBodyGetRoll(c\body) )
		Else
			phBodySetRot( c\body, phBodyGetPitch(c\body), phBodyGetYaw(c\body)-2.0, phBodyGetRoll(c\body) )
		EndIf 
	ElseIf KeyDown(205) ; Left 
        If l_bisGoBack = False
			phBodySetRot( c\body, phBodyGetPitch(c\body), phBodyGetYaw(c\body)-2.0, phBodyGetRoll(c\body) ) 
		Else
			phBodySetRot( c\body, phBodyGetPitch(c\body), phBodyGetYaw(c\body)+2.0, phBodyGetRoll(c\body) )
		EndIf 
	EndIf 
	
	
End Function 



Function TCar_SetPositionXZByWaypoint(p_CarName$,p_WayPointID,p_Relx#,p_Relz#)
	Local l_car.TCar = Null
	Local l_wp.TWayPoint = Null
	
	l_car = TCar_GetByName( p_CarName$ )
	If l_car = Null 
		RuntimeError "Function App_SetPositionCar Car name '"+p_CarName$ + "' does not exist."
	EndIf 
	
	l_wp = TWayPoint_Get.TWayPoint(p_WayPointID)
	If l_wp = Null 
		RuntimeError "Function App_SetPositionCar Waypoint ID '"+p_WayPointID + "' does not exist."
	EndIf 
	
	PositionEntity l_car\mesh, EntityX(l_wp\mesh),2, EntityZ(l_wp\mesh)
	
	Local l_wpNext.TWayPoint =TWayPoint_Get.TWayPoint(p_WayPointID+1)
	If l_wpNext = Null Then l_wpNext.TWayPoint =TWayPoint_Get.TWayPoint(1)
	If l_wpNext = Null
		RuntimeError "Function App_SetPositionCar Next Waypoint ID '"+p_WayPointID + "' does not exist."
	EndIf 
	
	
	RotateEntity l_car\mesh, EntityPitch(l_wp\mesh ), EntityYaw(l_wp\mesh ), EntityRoll(l_wp\mesh)  
	MoveEntity l_car\mesh, p_Relx#,0,p_Relz#
	TCar_SetBodyByMesh( l_car)
	l_car\wayp = l_wpNext
	
End Function 

Function TCar_Debug( c.TCar )
	Local x# = EntityX( c\mesh )
	Local y# = EntityY( c\mesh )
	Local z# = EntityZ( c\mesh )
	DebugLog c\name
	DebugLog "E Position X : " + x# + "	y  : " + y# +"	 z : " + z#
	
	x# = phBodyGetX(c\body)
	y# = phBodyGetY(c\body)
	z# = phBodyGetZ(c\body)
	DebugLog "B Position X : " + x# + "	y  : " + y# +"	 z : " + z#
	
	
	Local p# = EntityPitch( c\mesh )
	Local w# = EntityYaw( c\mesh )
	Local r# = EntityRoll( c\mesh )
	DebugLog "E Pitch : " + p# + "	Yaw  : " + w# +"	 Roll : " + r#
	
	
	p# = phBodyGetPitch(c\body)
	w# = phBodyGetYaw(c\body)
	r# = phBodyGetRoll(c\body)
	DebugLog "B Pitch : " + p# + "	Yaw  : " + w# +"	 Roll : " + r#
	
End Function 

;	
;	If v\bMissil = True And KeyHit(29)  
;		v\bMissil = False
;		
;		m = CopyEntity(g_App\TEMPLATE_MISSIL) 
;		PositionEntity m, EntityX( v\mesh ), EntityY( v\mesh ), EntityZ( v\mesh )
;		
;		v\MissilMesh = m
;		v\MissilLaunchTime = SetTimer( Rand(3000) )
;		v\MissilTarget = TCar_GetNearest( v )
;		PointEntity v\MissilMesh,v\MissilTarget\mesh 
;	EndIf 
;	
;	If TimeOut( v\MissilLaunchTime ) = False And v\MissilMesh <> 0
;		SmoothPoint( v\MissilMesh, v\MissilTarget\mesh, 0.1 )
;		MoveEntity v\MissilMesh, 0,0,1
;		
;		Local other.TCar
;		For other.TCar = Each TCar
;			If other\name <> v\name And v\MissilMesh > 0
;				If EntityDistance( other\mesh, v\MissilMesh ) < 1 Then
;					TExplosion_Create( v\MissilMesh,1 )
;					TExplosion_Create( other\mesh,1 )
;					other\bExploded=True
;					other\WaitExplodeTime=SetTimer(2000)
;					FreeEntity(v\MissilMesh)
;					v\MissilMesh=0
;					v\MissilTarget=Null
;				EndIf 
;			EndIf 
;		Next 
;	ElseIf TimeOut( v\MissilLaunchTime )  
;		FreeEntity v\MissilMesh
;		v\MissilLaunchTime = Null
;		v\MissilMesh = 0
;		v\MissilTarget = Null
;		v\bMissil = False 
;	EndIf
;End Function  


Function TCar_GetNearest.TCar( p_curr.TCar )
	Local other.TCar
	Local sNearestCarName$=""
	Local iNearestDistance#=9999999999.9
	Local d#
	For other.TCar = Each TCar
		If other\name <> p_curr\name
			d# = EntityDistance( p_curr\mesh, other\mesh )
			If d < iNearestDistance#
				iNearestDistance#=EntityDistance( p_curr\mesh, other\mesh )
				sNearestCarName$ = other\name
			EndIf 
		EndIf 
	Next 
	
	Return TCar_GetByName( sNearestCarName$ )
End Function	


Function TCar_Count()
	Local li_tot = 0
	Local c.TCar = Null 
	For c.TCar= Each TCar
		li_tot=li_tot+1
	Next
	Return li_tot
End Function 





Function TCar_Update() 
	Local l_v.Vec = Null
	Local l_vsub.Vec = Null
    Local c.TCar = Null
	Local Norm#
	Local l_bCanRoad = True 
	
	
	For c.TCar=Each TCar 
		l_bCanRoad = True 
		l_bCanRoad=TCar_Update_Item(c)
		If l_bCanRoad
			If c\is_Player = True
				TCar_UserControl(c)
				TCar_SetMeshByBody( c )
			Else
				TCar_FollowWaypoint(c,4)
				TCar_SetBodyByMesh( c )
			EndIf
		EndIf 
	Next			
	
;	If v\bMissil = True And KeyHit(29)  
;		v\bMissil = False
;		
;		m = CopyEntity(g_App\TEMPLATE_MISSIL) 
;		PositionEntity m, EntityX( v\mesh ), EntityY( v\mesh ), EntityZ( v\mesh )
;		
;		v\MissilMesh = m
;		v\MissilLaunchTime = SetTimer( Rand(3000) )
;		v\MissilTarget = TCar_GetNearest( v )
;		PointEntity v\MissilMesh,v\MissilTarget\mesh 
;	EndIf 
;	
;	If TimeOut( v\MissilLaunchTime ) = False And v\MissilMesh <> 0
;		SmoothPoint( v\MissilMesh, v\MissilTarget\mesh, 0.1 )
;		MoveEntity v\MissilMesh, 0,0,1
;		
;		Local other.TCar
;		For other.TCar = Each TCar
;			If other\name <> v\name And v\MissilMesh > 0
;				If EntityDistance( other\mesh, v\MissilMesh ) < 1 Then
;					TExplosion_Create( v\MissilMesh,1 )
;					TExplosion_Create( other\mesh,1 )
;					other\bExploded=True
;					other\WaitExplodeTime=SetTimer(2000)
;					FreeEntity(v\MissilMesh)
;					v\MissilMesh=0
;					v\MissilTarget=Null
;				EndIf 
;			EndIf 
;		Next 
;	ElseIf TimeOut( v\MissilLaunchTime )  
;		FreeEntity v\MissilMesh
;		v\MissilLaunchTime = Null
;		v\MissilMesh = 0
;		v\MissilTarget = Null
;		v\bMissil = False 
;	EndIf
	
End Function  



Function TCar_FollowWaypoint(c.TCar, p_dist_limit#=8.2) 
	; car can move when it touch the floor.
	If EntityY(c\mesh) > 0 Then Return 
	
	If EntityDistance(c\mesh,c\wayp\mesh) > p_dist_limit#
		
		uSmoothPoint( c\mesh, c\wayp\mesh, 0.1 )
		
		TFormVector 0,0,c\speed,c\mesh,0
		Local l_fX# = TFormedX()
		Local l_fY# = TFormedY()
		Local l_fZ# = TFormedZ()
		phBodySetVel( c\body, l_fX# , l_fY#, l_fZ# )
		
	Else  
 		If c\wayp\order_sequence >= c\count_waypoint 
			c\wayp = TWayPoint_Get(1)
			c\nb_loop = c\nb_loop + 1
		Else 
			c\wayp = TWaypoint_Next(c\wayp)
		EndIf
	EndIf 
	
End Function 



Function TCar_IA( p_CurrentCar.TCar)
	Local i.TItem = Null
	For i.TItem = Each TItem
		If i\cat = kITEM_MISSIL  Or i\cat = kITEM_SPEED
			
			If LOS_EntityInView ( p_CurrentCar\Los, p_CurrentCar\mesh, i\m ) > 0 Then
				uSmoothPoint( p_CurrentCar\mesh,i\m,0.3 )
				Exit
			EndIf 
		EndIf 
	Next  
	
	If p_CurrentCar\bMissil = True  
		p_CurrentCar\bMissil = False
		
		m = CopyEntity(g_App\TEMPLATE_MISSIL) 
		PositionEntity m, EntityX( p_CurrentCar\mesh ), EntityY( p_CurrentCar\mesh ), EntityZ( p_CurrentCar\mesh )
		
		p_CurrentCar\MissilMesh = m
		p_CurrentCar\MissilLaunchTime = SetTimer( Rand(3000) )
		p_CurrentCar\MissilTarget = TCar_GetNearest( p_CurrentCar )
		PointEntity p_CurrentCar\MissilMesh,p_CurrentCar\MissilTarget\mesh 
	EndIf 
	
	If TimeOut( p_CurrentCar\MissilLaunchTime ) = False And p_CurrentCar\MissilMesh <> 0
;		SmoothPoint( p_CurrentCar\MissilMesh, p_CurrentCar\MissilTarget\mesh, 0.1 )
		MoveEntity p_CurrentCar\MissilMesh, 0,0,1
		
		Local other.TCar
		For other.TCar = Each TCar
			If other\name <> p_CurrentCar\name And p_CurrentCar\MissilMesh > 0
				If EntityDistance( other\mesh, p_CurrentCar\MissilMesh ) < 1 Then
					TExplosion_Create( p_CurrentCar\MissilMesh,0 )
					TExplosion_Create( other\mesh,0 )
					other\bExploded=True
					other\WaitExplodeTime=SetTimer(2000)
					FreeEntity(p_CurrentCar\MissilMesh)
					p_CurrentCar\MissilMesh=0
					p_CurrentCar\MissilTarget=Null
				EndIf 
			EndIf 
		Next 
		
	ElseIf TimeOut( p_CurrentCar\MissilLaunchTime )  
		FreeEntity p_CurrentCar\MissilMesh
		p_CurrentCar\MissilLaunchTime = Null
		p_CurrentCar\MissilMesh = 0
		p_CurrentCar\MissilTarget = Null
		p_CurrentCar\bMissil = False 
	EndIf 
	
	
End Function	

Function TCar_MeshTemplate()
	; Build a car Template
	Local l_MDL =	CreateCube() 
	ScaleMesh(l_MDL,1,.35,2) 
	PositionMesh(l_MDL,0,.5,0) 
	
	Local l_cabine%=CreateCube	() 
	ScaleMesh(l_cabine,.9,.5,1) 
	PositionMesh(l_cabine,0,1,-.3) 
	AddMesh(l_cabine,l_MDL) 
	FreeEntity(l_cabine) 
	
	
 	uCelShading( l_MDL,0.05)
	HideEntity(l_MDL)
	
	Return l_MDL
End Function 


Function TCAR_Delete( p_c.TCar)
	phBodyDestroy(p_c\body)
	FreeEntity p_c\mesh
	Delete p_c
End Function 

Function TCAR_DeleteAll()
	Local l_c.TCar = Null
	For l_c.TCar = Each TCar
		TCAR_Delete( l_c )
	Next 
End Function 


;~IDEal Editor Parameters:
;~B#137#138
;~C#Blitz3D